home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1997 / MacHack 1997.toast / Hacks / Hacks ’93 / Windoid / InfinityWindoid.c < prev    next >
Text File  |  1993-06-18  |  41KB  |  1,278 lines

  1. /******************************************************************************
  2.  
  3.     NAME:
  4.         Infinity Windoid 2.3
  5.  
  6.     FILE:
  7.         InfinityWindoid.c
  8.  
  9.     WRITTEN BY:
  10.         Troy Gaul
  11.         Infinity Systems
  12.  
  13.         © 1991-93 Infinity Systems
  14.         All rights reserved.
  15.  
  16.     DESCRIPTION:
  17.         This file contains the source for a standalone code resource that
  18.         conforms to a Window DEFinition (WDEF), as defined by Apple Computer 
  19.         in Inside Macintosh.
  20.         
  21.         It provides a 'windoid' appearance. A windoid is a floating window
  22.         that appears above document windows in an application and is commonly
  23.         used for things like tool palettes, information windows, and the like.
  24.         
  25.         The WDEF included in the ResEdit file can be used as-is, but if a zoom
  26.         box is to be used, you will probably want to change the behavior of
  27.         what is included (by default, it zooms smaller rather than larger as
  28.         described below). This WDEF is created for System 6 and later, but it 
  29.         would be easy to modify it for earlier systems if this is important.
  30.  
  31.     FEATURES:
  32.         •    Supports System 7-style coloring of windows.
  33.         •    In System 7, the tinge color set by the user in the Color control 
  34.             panel is used.
  35.         •    Close box can be enabled from NewWindow by setting goAwayFlag.
  36.         •    Zoom box (special case) implemented, utilized by adding zoomDocProc
  37.             to the proc ID used to create the windoid.
  38.         •    Title bar can appear along the left of the window if 1 is added to 
  39.             the proc ID (with or without a zoom box).
  40.         •    For MacApp users, the left/top behavior of the proc ID can be 
  41.             switched.
  42.         •    System 6 coloring scheme is also supported (can be set in Kolor or
  43.             a similar control panel).
  44.         •    In System 7, DeviceLoop is used so the windoid will be drawn 
  45.             correctly even when it crosses monitors of differing depths.
  46.         •    In System 7, indexed color tables are checked to see if there are
  47.             enough different colors to display the color version (like the 
  48.             system WDEF).
  49.         
  50. -------------------------------------------------------------------------------
  51.  
  52.     HOW TO CONTACT THE AUTHOR:
  53.         Troy Gaul
  54.         Infinity Systems
  55.         
  56.         MicroFrontier, Inc.
  57.         3401 101st Street
  58.         Suite E
  59.         Des Moines, IA 50322
  60.         (515) 270-8109
  61.         
  62.         Internet:        t-gaul@grayhawk.rent.com
  63.                         
  64.         AppleLink:        mfrontier
  65.         
  66.         America Online:    ntwing
  67.                         mfrontier
  68.                                 
  69.         FAX:            (515) 278-6828
  70.  
  71. ******************************************************************************/
  72.  
  73.  
  74. //*****************************************************************************
  75. //    Include files
  76. //-----------------------------------------------------------------------------
  77.  
  78. #define SystemSixOrLater 1        
  79.     // This is used so that we can cut down on the code size in MPW. If you 
  80.     // think support for earlier systems is important, get rid of this. 
  81.     // Note: for this define to work under THINK C, MacHeaders should NOT
  82.     // be included.
  83.  
  84. //-----------------------------------------------------------------------------
  85.  
  86. #include <Memory.h>
  87. #include <QuickDraw.h>
  88. #include <OSUtils.h>
  89. #include <Windows.h>
  90. #include <Palettes.h>
  91. #include <ToolUtils.h>
  92. #include <Desk.h>
  93.  
  94. /******************************************************************************
  95. //    Conditional Compilation Options
  96. //-----------------------------------------------------------------------------
  97.  
  98. The #define's you may make include:
  99.  
  100.     ALLOW_ZOOM -    This option creates a windoid that supports a zoombox.
  101.                     To add the zoombox to a windoid, add zoomDocProc to the
  102.                     procID when creating the window. The application is
  103.                     responsible for setting the user state and standard state
  104.                     Rects of the window for zooming. (When a new window is 
  105.                     created, both of these are initialized to the bounds
  106.                     of the window. See the README for more information).
  107.  
  108.     STAYPUT_ZOOM -    This option will cause both the user and standard Rects to
  109.                     be changed together, causing the zoomed in and out state
  110.                     to have the same topLeft at all times. If this is not set,
  111.                     the standard and user states have their own 'memories'.
  112.                     (Note: this behavior is not fully tested.)
  113.  
  114.     MFI_ZOOM -        This will cause the WDEF to handle the zoom box in the way
  115.                     expected by MicroFrontier applications (the same way as
  116.                     version 2.2). That is, the other state that is used is one
  117.                     which has a title bar with a small area (in which the host
  118.                     program displays a label for the windoid).
  119.                     
  120.     ALLOW_VERT -    This determines if the code that is compiled will support
  121.                     a palette that has a vertical title bar along the left
  122.                     side of the window (rather than the top). To create such
  123.                     a window, add one to the varcode that is used.
  124.     
  125.     MACAPP_STYLE -    This determines if the varcodes that are supported are
  126.                     the one's I consider 'normal' or the ones MacApp's
  127.                     windoid WDEF knows about. Note, however, that this code
  128.                     only supports the 'smaller', title-less version that
  129.                     is available in MacApp's.
  130.  
  131.     THINK_STYLE -    This creates a version of the WDEF that is totally
  132.                     compatible with the varcodes used in the windoid WDEF 
  133.                     included with the THINK environments. Two things are done:
  134.                     varcode 0 gives a normal titlebar, varcode 2 gives a
  135.                     titlebar down the left side, and other varcodes (i.e.
  136.                     1,3,4,5,6,7) give no titlebar at all. (Note that in my
  137.                     version, a zoom box may also be used with this style.)
  138.                     Also, for the THINK style, ALWAYS_HILITE is also set, as
  139.                     this is how theirs works.
  140.  
  141.     ALWAYS_HILITE -    This will cause a windoid to be created that will always
  142.                     draw its title bar with gadgets and all. Normally, the
  143.                     windoid will draw the titlebar and frame in gray and
  144.                     empty when the window is not hilighted (like normal
  145.                     windows). Some programs, however, don't keep their
  146.                     windoids properly hilighted, so this will make them 
  147.                     appear to always be active.
  148.  
  149.     VERS_2_2_COMPATIBLE - This creates a version of the WDEF that is 
  150.                     functionally compatible with the version 2.2 windoid that
  151.                     I released. The only issue involved is the way the zooming
  152.                     is handled.
  153.  
  154. -----------------------------------------------------------------------------*/
  155.  
  156. #define ALLOW_ZOOM
  157. #define ALLOW_VERT
  158.  
  159. #define VERS_2_2_COMPATIBLE
  160.  
  161. //-----------------------------------------------------------------------------
  162.  
  163. #ifdef VERS_2_2_COMPATIBLE
  164.     #ifndef MFI_ZOOM
  165.     #define MFI_ZOOM
  166.     #endif
  167.     
  168.     #ifndef STAYPUT_ZOOM
  169.     #define STAYPUT_ZOOM
  170.     #endif
  171. #endif
  172.  
  173. //-----------------------------------------------------------------------------
  174.  
  175. #ifdef THINK_STYLE
  176.     #ifndef ALLOW_VERT
  177.     #define ALLOW_VERT
  178.     #endif
  179.  
  180.     #ifndef ALWAYS_HILITE
  181.     #define ALWAYS_HILITE
  182.     #endif
  183.  
  184.     #ifdef MACAPP_STYLE
  185.     #undef MACAPP_STYLE
  186.     #endif
  187. #endif
  188.  
  189. //-----------------------------------------------------------------------------
  190.  
  191. #ifdef MACAPP_STYLE
  192.     #ifdef ALLOW_VERT
  193.     #undef ALLOW_VERT
  194.     #endif
  195.  
  196.     #ifdef ALWAYS_HILITE
  197.     #undef ALWAYS_HILITE
  198.     #endif
  199. #endif
  200.  
  201. //*****************************************************************************
  202. //    Constants
  203. //-----------------------------------------------------------------------------
  204.  
  205. #define    kTitleHeight    11        
  206.     // This is the height of the windoid's titlebar.
  207.  
  208. #define kGadgetInset    2        
  209.     // inset from top/bottom of titlebar (with titlebar on top of window)
  210. #define kGadgetMargin    6        
  211.     // space between edge and gadget
  212. #define kGadgetSize        (kTitleHeight - (2 * kGadgetInset))
  213.  
  214. //-----------------------------------------------------------------------------
  215. //    Color table tinge percentage constants    
  216. //-----------------------------------------------------------------------------
  217.  
  218. #define    wTitleBarLightPct        0x1
  219. #define    wTitleBarDarkPct        0x8
  220. #define wCloseBoxColor            0x5
  221. #define    wXedBoxPct                0x8
  222. #define    wInactiveFramePct        0xA
  223.  
  224. //-----------------------------------------------------------------------------
  225. //    Color table constants    
  226. //-----------------------------------------------------------------------------
  227.  
  228. enum {
  229.     wHiliteColorLight = 5, 
  230.     wHiliteColorDark,
  231.     wTitleBarLight,
  232.     wTitleBarDark,
  233.     wDialogLight,
  234.     wDialogDark,
  235.     wTingeLight,
  236.     wTingeDark
  237. };
  238.     // These are the constants defined in the Apple technical note regarding
  239.     // Color, Windows, and System 7. Last I checked, they weren't in an Apple
  240.     // header file. (But the ones < 5 are, from the previous, pre-System 7
  241.     // coloring scheme.)
  242.  
  243. //-----------------------------------------------------------------------------
  244. //    Style variation constants    
  245. //-----------------------------------------------------------------------------
  246.  
  247. enum {
  248.     blackandwhite = 0,
  249.     sys7color,
  250.     sys6color
  251. };
  252.     // These constants represent the three types of window 'colorings' we
  253.     // support.
  254.     
  255. //-----------------------------------------------------------------------------
  256. //    MacApp style variations    
  257. //-----------------------------------------------------------------------------
  258.  
  259. #define kMacApp_toggleTBar    0x1    // bit 0 tells us whether to hilite/unhilite title bar
  260. #define kMacApp_hasTallTBar    0x2    // bit 1 is tall title bar bit (unsupported)
  261. #define kMacApp_hasGrow        0x4    // bit 2 is grow bit (std grow bit, unsupported)
  262. #define kMacApp_hasZoom        0x8    // bit 3 is zoom bit (standard zoom bit)
  263.  
  264. //*****************************************************************************
  265. //    Structures
  266. //-----------------------------------------------------------------------------
  267.  
  268. typedef struct WindoidData {
  269.     WStateData        wState;
  270.     unsigned int    closeToggle     : 1;
  271.     unsigned int    zoomToggle         : 1;
  272.     unsigned int    isSystem7         : 1;
  273.     unsigned int    hasCQD            : 1;
  274.     unsigned int    isHoriz         : 1;
  275.     unsigned int    ignoreHilite    : 1;
  276.     unsigned int    hasTitlebar        : 1;
  277. } WindoidData, **WindoidDataHandle;
  278.  
  279. #define WindData (**(WindoidDataHandle)(window->dataHandle))
  280.     // This macro is used so I can access the 'globals' easily. Note: the
  281.     // variable containing the window must be 'window', and it must be in
  282.     // scope at the time of the usage of this macro.
  283.     // Also, they aren't REALLY globals, becuase they're kept for EACH window,
  284.     // which is why I use a bitfield, trying to keep this as small as
  285.     // possible.)
  286.  
  287. //*****************************************************************************
  288. //    Function Prototypes                                 
  289. //-----------------------------------------------------------------------------
  290.  
  291. void DoWInit(WindowPeek window, long param, short varCode);
  292. void DoWDispose(WindowPeek window, long param);
  293. long DoWHit(WindowPeek window, long param);
  294. void DoWDraw(WindowPeek window, long param);
  295. void DoWCalcRgns(WindowPeek window, long param);
  296. void DoWGrow(WindowPeek window, long param);
  297. void DoWDrawGIcon(WindowPeek window, long param);
  298.  
  299. void SyncPorts(void);
  300.  
  301. //*****************************************************************************
  302. //    Windoid Main Function                                                                     
  303. //-----------------------------------------------------------------------------
  304. //    This is the main entry point for all calls to this code resource. It
  305. //    dispatches to routines that correspond to the message it is given.
  306. //-----------------------------------------------------------------------------
  307.  
  308. pascal long main( short varCode, WindowPeek window, 
  309.                   short message, long param ) {
  310.     GrafPtr        savePort;
  311.     long        result;
  312.     Boolean        isADrawMsg;
  313.     
  314.     // This sets up the appropriate drawing environment, but only for those
  315.     // messages for which we actually need to draw.
  316.     isADrawMsg = (message == wDraw || message == wHit || message == wDrawGIcon);
  317.     if (isADrawMsg && WindData.hasCQD) {
  318.         GetPort(&savePort);
  319.         SyncPorts();
  320.     }
  321.     
  322.     switch (message) {
  323.         case wNew:            DoWInit(window, param, varCode);
  324.                             break;
  325.         
  326.         case wDispose:        DoWDispose(window, param);
  327.                             break;
  328.  
  329.         case wDraw:            DoWDraw(window, param & 0xFFFF);
  330.                             break;
  331.             // There's a tech note that says that for the draw message, only
  332.             // the low-order word of param is set correctly, so we should do
  333.             // this (AND with 0xFFFF) to be sure we're looking at the correct value.
  334.             
  335.         case wHit:            result = DoWHit(window, param);        
  336.                             break;
  337.         
  338.         case wCalcRgns:        DoWCalcRgns(window, param);
  339.                             break;
  340.         
  341.         case wGrow:            DoWGrow(window, param);
  342.                             break;
  343.                             
  344.         case wDrawGIcon:    DoWDrawGIcon(window, param);
  345.                             break;
  346.     }
  347.     
  348.     if (isADrawMsg)
  349.         SetPort(savePort);
  350.     
  351.     return result;
  352. }
  353.  
  354. //*****************************************************************************
  355. //    Environment-determining Routines                                                                             
  356. //-----------------------------------------------------------------------------
  357.     // These use SysEnvirons so we don't have to rely on Gestalt being available
  358.     // and so MPW won't include that code in our resource.
  359.  
  360. short HasSystem7( void ) {
  361.     SysEnvRec    theWorld;
  362.     long        theSysVers;
  363.     
  364.     if (SysEnvirons(1, &theWorld) == noErr) {
  365.         theSysVers = (long)theWorld.systemVersion;
  366.         return (theSysVers >= 0x0700);
  367.     } else
  368.         return false;
  369. }
  370.  
  371. //-----------------------------------------------------------------------------
  372.  
  373. short HasCQDraw( void ) {
  374.     SysEnvRec    theWorld;
  375.     
  376.     if ((SysEnvirons(1, &theWorld) == noErr) && theWorld.hasColorQD)
  377.         return 1;
  378.     else
  379.         return 0;
  380. }
  381.  
  382. //*****************************************************************************
  383. //    SyncPorts
  384. //-----------------------------------------------------------------------------
  385.     //    Straight from the pages of _Macintosh Programming Secrets_, Second 
  386.     //    Edition by Scott Knaster and Keith Rollin (page 425). (except that this
  387.     //    version doesn't check Gestalt, it will only be called if CQD is running)
  388.     //    This routines was added to 2.3. It makes sure the drawing environment 
  389.     //    is set correctly if the system has color. This is not needed for the 
  390.     //    code in this WDEF as it is, but if a DoWDrawGIcon handler is implemented, 
  391.     //    this is needed to make sure the drawing environment is set as Apple 
  392.     //    tells us it will be for drawing the gray, xor'ed border.
  393.  
  394. void SyncPorts( void ) {
  395.     GrafPtr        bwPort;
  396.     CGrafPtr    colorPort;
  397.     
  398.     GetWMgrPort(&bwPort);
  399.     GetCWMgrPort(&colorPort);
  400.     SetPort((GrafPtr)colorPort);
  401.     
  402.     BlockMove(&bwPort->pnLoc, &colorPort->pnLoc, 10);
  403.     BlockMove(&bwPort->pnVis, &colorPort->pnVis, 14);
  404.     PenPat((ConstPatternParam)&bwPort->pnPat);
  405.     BackPat((ConstPatternParam)&bwPort->bkPat);
  406. }
  407.  
  408. //*****************************************************************************
  409. //    Color Mixing Routines                                                                     
  410. //-----------------------------------------------------------------------------
  411.  
  412. void GetWctbColor( WindowPeek window, short partCode, RGBColor *theColor ) {
  413.     // Given a partCode, return the RGBColor associated with it. (Using the
  414.     // default window color table.)
  415.     AuxWinHandle    awHndl;
  416.     short            junkResult;
  417.     
  418.     junkResult = GetAuxWin((WindowPtr)window, &awHndl);
  419.     *theColor = (**(WCTabHandle)((**awHndl).awCTable)).ctTable[partCode].rgb;
  420. }
  421.  
  422. //-----------------------------------------------------------------------------
  423.  
  424. void SetWctbColor( WindowPeek window, short partCode ) {
  425.     RGBColor        theColor;
  426.  
  427.     GetWctbColor(window, partCode, &theColor);
  428.     RGBForeColor(&theColor);
  429. }
  430.  
  431. //-----------------------------------------------------------------------------
  432. #pragma processor 68020
  433.     // Note: this should be okay because this will only be called if we are
  434.     // doing System 7 color, which requires Color Quickdraw, which is only
  435.     // available on systems with 68020's or better. Again, this is done to
  436.     // reduce code size. If it isn't compiled this way, several routines will
  437.     // be added to handle the long integer arithmetic. We would like to avoid
  438.     // that.
  439.  
  440. void MixColor( const RGBColor *lightColor, const RGBColor *darkColor, 
  441.                short shade, RGBColor *result ) {
  442.     shade = 0x0F - shade;
  443.         // This is necessary because we give shades between light and
  444.         // dark (0% is light), but for colors, $0000 is black and $FFFF 
  445.         //    is dark.
  446.  
  447.     result->red      = ((lightColor->red - darkColor->red) * shade / 15) 
  448.                      + darkColor->red;
  449.     result->green = ((lightColor->green - darkColor->green) * shade / 15)
  450.                      + darkColor->green;
  451.     result->blue  = ((lightColor->blue - darkColor->blue) * shade / 15) 
  452.                      + darkColor->blue;
  453. }
  454.  
  455. #pragma processor 68000
  456. //-----------------------------------------------------------------------------
  457.  
  458. void AvgWctbColor( WindowPeek window, short light, short dark, short shade, 
  459.                    RGBColor *theColor ) {
  460.     // Mix two parts by the given shade, which is actually a value
  461.     // between 0 (0%) and 15 (100%), return the RGBColor.
  462.     RGBColor    lightColor;
  463.     RGBColor    darkColor;
  464.  
  465.     GetWctbColor(window, light, &lightColor);
  466.     GetWctbColor(window, dark, &darkColor);
  467.     MixColor(&lightColor, &darkColor, shade, theColor);
  468. }
  469.  
  470. //*****************************************************************************
  471. //    Helper Functions
  472. //-----------------------------------------------------------------------------
  473.  
  474. void FrameBox( const Rect *theRect ) {
  475.     Rect tempRect = *theRect;
  476.     
  477.     FrameRect(theRect);
  478.     InsetRect(&tempRect, 1, 1);
  479.     EraseRect(&tempRect);
  480. }
  481.  
  482. //-----------------------------------------------------------------------------
  483.  
  484. void GetGlobalContentRect( WindowPeek window, Rect *contentRect ) {
  485.     GrafPtr savePort;
  486.  
  487.     GetPort(&savePort);
  488.     SetPort((GrafPtr)window);
  489.     *contentRect = window->port.portRect;
  490.     LocalToGlobal((Point*)&contentRect->top);
  491.     LocalToGlobal((Point*)&contentRect->bottom);
  492.     SetPort(savePort);
  493. }
  494.  
  495. //*****************************************************************************
  496. //    Routines to get Rects for title bar parts                                             
  497. //-----------------------------------------------------------------------------
  498.  
  499. void GetTitleBar( WindowPeek window, Rect *titleBar ) {
  500.     *titleBar = (**(window->strucRgn)).rgnBBox;
  501.  
  502.     if (WindData.isHoriz) {                                        
  503.         // title bar on top
  504.         titleBar->bottom = titleBar->top + kTitleHeight;
  505.         titleBar->right -= 1;        // shadow compensation
  506.     } else {                                                            
  507.         // title bar on left
  508.         titleBar->right = titleBar->left + kTitleHeight;
  509.         titleBar->bottom -= 1;         // shadow compensation
  510.     }
  511. }
  512.  
  513. //-----------------------------------------------------------------------------
  514.  
  515. void GetCloseBox( WindowPeek window, const Rect *titleRect, Rect *theRect ) {
  516.     #pragma unused(window)
  517.  
  518.     *theRect = *titleRect;
  519.     if (WindData.isHoriz)
  520.         InsetRect(theRect, kGadgetMargin, kGadgetInset);    // titlebar on top
  521.     else
  522.         InsetRect(theRect, kGadgetInset, kGadgetMargin);    // titlebar on left
  523.  
  524.     theRect->bottom = theRect->top  + kGadgetSize;
  525.     theRect->right  = theRect->left + kGadgetSize;
  526. }
  527.  
  528. //-----------------------------------------------------------------------------
  529. #ifdef ALLOW_ZOOM
  530.  
  531. void GetZoomBox( WindowPeek window, const Rect *titleRect, Rect *theRect ) {
  532.     #pragma unused(window)
  533.  
  534.     *theRect = *titleRect;
  535.     if (WindData.isHoriz)
  536.         InsetRect(theRect, kGadgetMargin, kGadgetInset);    // titlebar on top
  537.     else
  538.         InsetRect(theRect, kGadgetInset, kGadgetMargin);    // titlebar on left
  539.  
  540.     theRect->top = theRect->bottom - kGadgetSize;
  541.     theRect->left = theRect->right - kGadgetSize;
  542. }
  543.  
  544. #endif
  545. //*****************************************************************************
  546. //    Zoom handling                                                     
  547. //-----------------------------------------------------------------------------
  548. #ifdef ALLOW_ZOOM
  549.     
  550. void SetZoomRects( WindowPeek window ) {
  551.     Rect        contRect;
  552.     
  553.     if (window->spareFlag) {
  554.         GetGlobalContentRect(window, &contRect);
  555.         WindData.wState.stdState = contRect;
  556. #ifdef MFI_ZOOM
  557.         if (WindData.isHoriz)                            // titlebar on top
  558.             contRect.bottom = contRect.top + 12;
  559.         else                                            // titlebar on left
  560.             contRect.right = contRect.left + 12;
  561. #endif
  562.         WindData.wState.userState = contRect;
  563.             // the stdState and user state might be backwards from how they
  564.             // would normally be used by an application. Check this for your
  565.             // own use and change them if necessary.
  566.     }
  567. }
  568.  
  569. //-----------------------------------------------------------------------------
  570.  
  571. long GetZoomHitType( WindowPeek window ) {
  572.     Rect        contRect;
  573.     Rect        stdRect;
  574.     
  575.     contRect = (**(window->contRgn)).rgnBBox;
  576.     stdRect = WindData.wState.stdState;
  577.     OffsetRect(&stdRect, -stdRect.left + contRect.left, 
  578.                          -stdRect.top + contRect.top);
  579.         // make topLeft the same for content and standard rects, and compare
  580.  
  581.     if (EqualRect(&contRect, &stdRect))
  582.         return wInZoomIn;        // go to user state (make small, MFI)
  583.     else
  584.         return wInZoomOut;        // go to standard state (make normal, MFI)
  585. }
  586.  
  587. #endif
  588. //*****************************************************************************
  589. //    DoWInit -- Windoid initialization                                                     
  590. //-----------------------------------------------------------------------------
  591.  
  592. void DoWInit( WindowPeek window, long param, short varCode ) {
  593.     #pragma unused(param)
  594.     Handle zoomStuff;
  595.  
  596.     window->spareFlag = false;
  597.     zoomStuff = NewHandle(sizeof(WindoidData));
  598.     if (zoomStuff) {
  599.         window->dataHandle         = zoomStuff;
  600.         WindData.closeToggle     = 0;
  601.         WindData.hasCQD            = HasCQDraw();
  602.         WindData.isSystem7         = HasSystem7();
  603.         WindData.hasTitlebar    = true;
  604.         WindData.ignoreHilite    = false;
  605.  
  606. #ifdef ALLOW_VERT
  607.         WindData.isHoriz         = (((varCode & 1) == 0) && ((varCode & 2) == 0));
  608. #else
  609.         WindData.isHoriz         = true;
  610. #endif
  611.  
  612. #ifdef ALLOW_ZOOM
  613.         WindData.zoomToggle        = 0;
  614.         window->spareFlag        = ((zoomDocProc & varCode) != 0);
  615.         SetZoomRects(window);
  616. #endif
  617.  
  618. #ifdef ALWAYS_HILITE
  619.         WindData.ignoreHilite    = true;
  620. #endif
  621.  
  622. #ifdef MACAPP_STYLE
  623.         WindData.ignoreHilite    = !((kMacApp_toggleTBar & varCode) != 0);
  624. #endif
  625.  
  626. #ifdef THINK_STYLE
  627.         if (((varCode & 7) != 0) && ((varCode & 7) != 2))
  628.             WindData.hasTitlebar    = false;
  629. #endif
  630.     }
  631. }
  632.  
  633. //*****************************************************************************
  634. //    DoWDispose -- Windoid disposal                                                         
  635. //-----------------------------------------------------------------------------
  636.  
  637. void DoWDispose( WindowPeek window, long param ) {
  638.     #pragma unused(param)
  639.  
  640.     if (window->dataHandle)
  641.         DisposeHandle(window->dataHandle);
  642. }
  643.  
  644. //*****************************************************************************
  645. //    DoWHit -- Windoid hit routine                                                             
  646. //-----------------------------------------------------------------------------
  647.  
  648. long DoWHit( WindowPeek window, long param ) {
  649.     Rect    stdRect;
  650.     Rect    usrRect;
  651.     Rect    titleRect;
  652.     Rect    contentRect;
  653.     Rect    theRect;
  654.     Point    hitPt;
  655.     long    result;
  656.  
  657.     hitPt.v = HiWord(param);
  658.     hitPt.h = LoWord(param);
  659.     
  660.     result = wNoHit;
  661.     if (PtInRgn(hitPt, window->contRgn))
  662.         result = wInContent;
  663.     else {
  664.         GetTitleBar(window, &titleRect);
  665.         if (WindData.hasTitlebar && PtInRect(hitPt, &titleRect)) {
  666.             result = wInDrag;
  667.             if (WindData.ignoreHilite || window->hilited) {
  668.                 if (window->goAwayFlag) {
  669.                     GetCloseBox(window, &titleRect, &theRect);
  670.                     if (PtInRect(hitPt, &theRect))
  671.                         result = wInGoAway;
  672.                 }
  673. #ifdef ALLOW_ZOOM
  674.                 if (window->spareFlag) {
  675.                     GetZoomBox(window, &titleRect, &theRect);
  676.                     if (PtInRect(hitPt, &theRect)) {
  677.                         result = GetZoomHitType(window);
  678.  
  679.                         // Calculate Offset for Zoom Rects (make sure they
  680.                         // are up to date)
  681.                         contentRect = (**(window->contRgn)).rgnBBox;
  682.                         stdRect = WindData.wState.stdState;
  683.                         usrRect = WindData.wState.userState;
  684.                         
  685. #ifdef STAYPUT_ZOOM
  686.                         OffsetRect(&(WindData.wState.stdState), 
  687.                                    contentRect.left - stdRect.left,
  688.                                    contentRect.top  - stdRect.top);
  689.                         OffsetRect(&(WindData.wState.userState), 
  690.                                    contentRect.left - usrRect.left, 
  691.                                    contentRect.top  - usrRect.top);
  692. #else
  693.                         if (result == wInZoomIn) {
  694.                             OffsetRect(&(WindData.wState.stdState), 
  695.                                        contentRect.left - stdRect.left,
  696.                                        contentRect.top  - stdRect.top);
  697.                         } else {
  698.                             OffsetRect(&(WindData.wState.userState), 
  699.                                        contentRect.left - usrRect.left, 
  700.                                        contentRect.top  - usrRect.top);
  701.                         }
  702. #endif                        
  703.                     }
  704.                 }
  705. #endif
  706.             }
  707.         }
  708.     }
  709.     return result;
  710. }
  711.  
  712. //*****************************************************************************
  713. //    DoWDraw -- Windoid drawing routines                                                     
  714. //-----------------------------------------------------------------------------
  715.  
  716. void DrawCloseBox( WindowPeek window, short variation, Rect *theRect ) {
  717.     RGBColor    theColor;
  718.     Rect        tempRect;
  719.  
  720.     switch (variation) {
  721.         case blackandwhite:
  722.             FrameBox(theRect);
  723.             break;
  724.         
  725.         case sys6color:
  726.             SetWctbColor(window, wHiliteColor);
  727.             GetWctbColor(window, wTitleBarColor, &theColor);
  728.             RGBBackColor(&theColor);
  729.             FrameBox(theRect);
  730.             break;
  731.         
  732.         case sys7color:
  733.             SetWctbColor(window, wTingeLight);
  734.             tempRect = *theRect;
  735.             tempRect.top++;
  736.             tempRect.left++;
  737.             FrameRect(&tempRect);
  738.         
  739.             SetWctbColor(window, wTingeDark);
  740.         
  741.             MoveTo(theRect->right - 1, theRect->top);
  742.             LineTo(theRect->left, theRect->top);
  743.             LineTo(theRect->left, theRect->bottom - 1);
  744.             
  745.             MoveTo(theRect->right - 2, theRect->top + 2);
  746.             LineTo(theRect->right - 2, theRect->bottom - 2);
  747.             LineTo(theRect->left + 2, theRect->bottom - 2);
  748.         
  749.             AvgWctbColor(window, wHiliteColorLight, wHiliteColorDark, 
  750.                          wCloseBoxColor, &theColor);
  751.             RGBForeColor(&theColor);
  752.             tempRect = *theRect;
  753.             InsetRect(&tempRect, 2, 2);
  754.             PaintRect(&tempRect);
  755.             
  756.             break;
  757.     }
  758.         
  759. }
  760.  
  761. //*****************************************************************************
  762. //    DrawZoomBox -- Draw zoom box
  763. //-----------------------------------------------------------------------------
  764. #ifdef ALLOW_ZOOM
  765.  
  766. void DrawZoomBox( WindowPeek window, short variation, Rect *theRect ) {
  767.     Rect        tempRect;
  768.     RGBColor    theColor;
  769.  
  770.     switch (variation) {
  771.         case blackandwhite:
  772.         case sys6color:
  773.             if (variation != blackandwhite) {
  774.                 SetWctbColor(window, wHiliteColor);
  775.                 GetWctbColor(window, wTitleBarColor, &theColor);
  776.                 RGBBackColor(&theColor);
  777.             }            
  778.             FrameBox(theRect);
  779.             tempRect = *theRect;
  780.             tempRect.bottom -= 3;
  781.             tempRect.right -= 3;
  782.             FrameRect(&tempRect);
  783.             break;
  784.         
  785.         case sys7color:
  786.             DrawCloseBox(window, variation, theRect);
  787.             SetWctbColor(window, wTingeDark);
  788.         
  789.             MoveTo(theRect->right - 4, theRect->top + 2);
  790.             LineTo(theRect->right - 4, theRect->bottom - 4);
  791.             LineTo(theRect->left + 2, theRect->bottom - 4);
  792.             break;
  793.     }
  794. }
  795.  
  796. #endif
  797. //*****************************************************************************
  798. //    DrawXedBox -- Draw close or zoom box with an X in it (or inverted in B&W)
  799. //-----------------------------------------------------------------------------
  800.  
  801. void DrawXedBox( WindowPeek window, short variation, Rect *theRect ) {
  802.     RGBColor theColor;
  803.  
  804.     switch (variation) {
  805.         case blackandwhite:
  806.             PaintRect(theRect);
  807.             break;
  808.             
  809.         case sys6color:
  810.             SetWctbColor(window, wHiliteColor);
  811.             PaintRect(theRect);
  812.             break;
  813.             
  814.         case sys7color:
  815.             AvgWctbColor(window, wTingeLight, wTingeDark, wXedBoxPct, &theColor);
  816.             RGBForeColor(&theColor);
  817.             PaintRect(theRect);
  818.             
  819.             SetWctbColor(window, wFrameColor);
  820.             FrameRect(theRect);
  821.         
  822.             MoveTo(theRect->left, theRect->top);                // Draw the 'X'
  823.             LineTo(theRect->right - 1, theRect->bottom - 1);
  824.             MoveTo(theRect->right - 1, theRect->top);
  825.             LineTo(theRect->left, theRect->bottom - 1);
  826.             break;
  827.     }
  828. }
  829.  
  830. //*****************************************************************************
  831. //    DrawTitlePat -- Draw pattern into the title bar
  832. //-----------------------------------------------------------------------------
  833.     // This routine actually draws the pattern into the titlebar. Note: it
  834.     // takes a Rect as a parameter (not by address) because it goes ahead and
  835.     // modifies it. I figured this was no worse than needing to copy it into
  836.     // a local variable, so I went ahead and did it this way.
  837.  
  838. void DrawTitlePatPat( WindowPeek window, Rect titleRect ) {
  839.     #pragma unused (window)
  840.     Pattern        titlePat;
  841.     long        patternSeed;
  842.     Point        corner;
  843.     Rect        tempRect;
  844.     RgnHandle    titleRgn;
  845.     RgnHandle    tempRgn;
  846.     
  847.     SetPt(&corner, titleRect.left, titleRect.top);
  848.     LocalToGlobal(&corner);
  849.  
  850.     // Choose correct pattern, depending on position of window in global
  851.     // coordinates. (Concept of new (2.3) version taken from _Macintosh 
  852.     // Programming Secrets_, Second Edition, by Scott Knaster and Keith 
  853.     // Rollin, page 423.)
  854.     patternSeed = 0x00550055;
  855.     if (!(corner.h & 1))
  856.         patternSeed <<= 1;
  857.     if (!(corner.v & 1))
  858.         patternSeed <<= 8;
  859.     *((long*)&titlePat + 1) = *(long*)&titlePat = patternSeed;
  860.  
  861.     // Draw the pattern into the titlebar, but only the areas needed
  862.     // (i.e. don't draw into close, zoom boxes)
  863.     titleRgn = NewRgn();
  864.     tempRgn = NewRgn();
  865.     RectRgn(titleRgn, &titleRect);
  866.     InsetRgn(titleRgn, 1, 1);
  867.     if (window->goAwayFlag) {
  868.         GetCloseBox(window, &titleRect, &tempRect);
  869.         RectRgn(tempRgn, &tempRect);
  870.         DiffRgn(titleRgn, tempRgn, titleRgn);
  871.     }
  872.     if (window->spareFlag) {
  873.         GetZoomBox(window, &titleRect, &tempRect);
  874.         RectRgn(tempRgn, &tempRect);
  875.         DiffRgn(titleRgn, tempRgn, titleRgn);
  876.     }
  877.     FillRgn(titleRgn, (ConstPatternParam)&titlePat);
  878.     DisposeRgn(titleRgn);
  879.     DisposeRgn(tempRgn);
  880.  
  881. //    -- used to be done this way, which would still work, but the new way
  882. //       prevents a (barely noticeable) flash of the gadgets
  883. //    InsetRect(&titleRect, 1, 1);
  884. //    FillRect(&titleRect, &titlePat);
  885. }
  886.  
  887. //-----------------------------------------------------------------------------
  888.  
  889. void DrawTitlePat( WindowPeek window, short variation, Rect *titleRect ) {
  890.     RGBColor theColor;
  891.  
  892.     switch (variation) {
  893.         case blackandwhite:
  894.             ForeColor(blackColor);
  895.             BackColor(whiteColor);
  896.             break;
  897.             
  898.         case sys6color:
  899.             SetWctbColor(window, wHiliteColor);
  900.             GetWctbColor(window, wTitleBarColor, &theColor);
  901.             RGBBackColor(&theColor);
  902.             break;
  903.  
  904.         case sys7color:
  905.             AvgWctbColor(window, wHiliteColorLight, wHiliteColorDark, 
  906.                          wTitleBarLightPct, &theColor);
  907.             RGBBackColor(&theColor);
  908.             AvgWctbColor(window, wHiliteColorLight, wHiliteColorDark, 
  909.                          wTitleBarDarkPct, &theColor);
  910.             RGBForeColor(&theColor);
  911.             break;
  912.     }
  913.     DrawTitlePatPat(window, *titleRect);
  914. }
  915.  
  916. //*****************************************************************************
  917. //    CheckDisplay -- Check to see if we are using color title bars
  918. //-----------------------------------------------------------------------------
  919.  
  920. Boolean CheckAvailable( WindowPeek window, short light, short dark, 
  921.                         short count, short *ramp ) {
  922.     // Given a light and dark index value, a count, and and an array of
  923.     // 'percentage' values (0x0 to 0xF, or 0 to 15), see if each of the
  924.     // values in the ramp maps to a different color on the screen. If not,
  925.     // we need to use black-and-white.
  926.     
  927.     RGBColor    theColor;
  928.     short        i;
  929.     short        result = true;
  930.     short        colorIndex = -1;
  931.     short        lastIndex;
  932.                 
  933.     for (i = 0 ; i < count && result == true ; i++) {
  934.         AvgWctbColor(window, light, dark, ramp[i], &theColor);    
  935.         lastIndex = colorIndex;
  936.         colorIndex = Color2Index(&theColor);
  937.         if (i > 0 && colorIndex == lastIndex)
  938.             result = false;
  939.     }
  940.     return result;
  941. }
  942.  
  943. //-----------------------------------------------------------------------------
  944.  
  945. short CheckDisplay( short theDepth, short deviceFlags, 
  946.                     GDHandle targetDevice, WindowPeek window ) {
  947.     Boolean        inColor;
  948.     short        result;
  949.     RGBColor    testColor;
  950.     GDHandle    saveDevice;
  951.         
  952.     inColor = WindData.hasCQD && (deviceFlags & (0x0001 << gdDevType));
  953.     
  954.     result = blackandwhite;                    // assume Black and White
  955.     if (theDepth >= 4) {
  956.         if (!WindData.isSystem7) {
  957.             result = sys6color;                // System 6.0.x Color
  958.         } else {
  959.             GetWctbColor(window, wTingeLight, &testColor);
  960.             if (testColor.red != 0 || testColor.green != 0 || testColor.blue != 0) 
  961.                 // check for B&W control panel setting, otherwise:
  962.                 result = sys7color;            // System 7.0 Color
  963.         }
  964.     }
  965.     // Note: Since I didn't find another way to see if the user had changed
  966.     // the settings in the Color control panel to the Black-and-white setting,
  967.     // I actually check to see if the rgb components of the light tinge color
  968.     // are non-zero (which seemed to be the case with that setting). 
  969.     
  970.     if (result == sys7color && inColor && theDepth <= 8) {
  971.         short        list[5] = { 0x00, 0x07, 0x08, 0x0A, 0x0D };
  972.             // Make sure this array is allcated big enough for the largest ramp.
  973.  
  974.         result = blackandwhite;
  975.         saveDevice = GetGDevice();
  976.         SetGDevice(targetDevice);
  977.         if (CheckAvailable(window, wHiliteColorLight, wHiliteColorDark, 5, list)) {
  978.             list[0] = 0x00;
  979.             list[1] = 0x01;
  980.             list[2] = 0x04;
  981.             if (CheckAvailable(window, wTitleBarLight, wTitleBarDark, 3, list)) {
  982.                 list[0] = 0x00;
  983.                 list[1] = 0x04;
  984.                 list[2] = 0x0F;
  985.                 if (CheckAvailable(window, wTingeLight, wTingeDark, 3, list))
  986.                     result = sys7color;
  987.             }
  988.         }
  989.         SetGDevice(saveDevice);
  990.     }
  991.     // This part checks to see if there are 'enough' colors to draw the 
  992.     // title bar in color under System 7. It is supposed to do so in the
  993.     // same way that Apple's system WDEF does. I essentially took the 
  994.     // assembly code that Apple released and tried to make this use the
  995.     // same algorithm. Note: the values in list for the first CheckAvailable
  996.     // call are set up in the variable declaration in the top of the routine.
  997.     // Don't you just LOVE what C lets you do?
  998.  
  999.     return result;
  1000. }
  1001.  
  1002. //*****************************************************************************
  1003. //    Windoid drawing loop
  1004. //-----------------------------------------------------------------------------
  1005.     // This information is used to communicate with DeviceLoop callback routine.
  1006.  
  1007. typedef struct WDLDataRec {
  1008.     WindowPeek    wdlWindow;
  1009.     long        wdlParam;
  1010. } WDLDataRec;
  1011.  
  1012. //-----------------------------------------------------------------------------
  1013.     // This routine actually does the real work of the drawing of stuff into
  1014.     // the window.
  1015.  
  1016. pascal void WindoidDrawLoop( short depth, short deviceFlags, 
  1017.                              GDHandle targetDevice, WDLDataRec *userData ) {
  1018.     #pragma unused(targetDevice)
  1019.     Rect        titleRect;
  1020.     Rect         tempRect;
  1021.     RGBColor    theColor;
  1022.     WindowPeek    window;
  1023.     short        fancy;
  1024.  
  1025.     window = userData->wdlWindow;
  1026.     fancy = CheckDisplay(depth, deviceFlags, targetDevice, window);
  1027.     
  1028.     if (window->visible)
  1029.         switch (userData->wdlParam) {
  1030.             case wNoHit:
  1031.                 BackColor(whiteColor);
  1032.                 
  1033.                 // Draw titlebar
  1034.                 if (WindData.hasTitlebar) {
  1035.                     GetTitleBar(window, &titleRect);
  1036.                     switch (fancy) {
  1037.                         case blackandwhite:
  1038.                             ForeColor(blackColor);
  1039.                             break;
  1040.     
  1041.                         case sys6color:
  1042.                             SetWctbColor(window, wFrameColor);
  1043.                             break;
  1044.     
  1045.                         case sys7color:
  1046.                             if (WindData.ignoreHilite || window->hilited)
  1047.                                 SetWctbColor(window, wFrameColor);
  1048.                             else {
  1049.                                 AvgWctbColor(window, wHiliteColorLight, wHiliteColorDark,
  1050.                                              wInactiveFramePct, &theColor);
  1051.                                 RGBForeColor(&theColor);
  1052.                             }
  1053.                             break;
  1054.                     }
  1055.                     FrameRect(&titleRect);
  1056.                 }
  1057.                 
  1058.                 if (WindData.ignoreHilite || window->hilited) {
  1059.                     if (WindData.hasTitlebar)
  1060.                         DrawTitlePat(window, fancy, &titleRect);
  1061.                 
  1062.                     // Draw close box
  1063.                     if (window->goAwayFlag) {    
  1064.                         GetCloseBox(window, &titleRect, &tempRect);
  1065.                         DrawCloseBox(window, fancy, &tempRect);
  1066.                     }
  1067.                         // Note: I have seen at least one windoid WDEF that is used
  1068.                         // by some applications that does not utilize this flag.
  1069.                         // In that case, I think it always had a close box (or it
  1070.                         // might even have used the varcode to determine this, but
  1071.                         // that wouldn't seem to be a good thing to do). Anyway, if
  1072.                         // you always want the close box, just comment out the 'if'
  1073.                         // line (and the close brace line) above.
  1074.  
  1075. #ifdef ALLOW_ZOOM
  1076.                     // Draw zoom box
  1077.                     if (window->spareFlag) {
  1078.                         GetZoomBox(window, &titleRect, &tempRect);
  1079.                         DrawZoomBox(window, fancy, &tempRect);
  1080.                     }
  1081. #endif
  1082.                 } else {
  1083.                     tempRect = titleRect;        // dimmed titlebar
  1084.                     InsetRect(&tempRect,1,1);
  1085.                     EraseRect(&tempRect);
  1086.                 }
  1087.  
  1088.                 // Draw content frame and shadow
  1089.                 tempRect = (**(window->strucRgn)).rgnBBox;
  1090.                 tempRect.bottom--;
  1091.                 tempRect.right--;
  1092.                 
  1093.                 switch (fancy) {
  1094.                     case blackandwhite:
  1095.                         ForeColor(blackColor);
  1096.                         break;
  1097.  
  1098.                     case sys6color:
  1099.                         SetWctbColor(window, wFrameColor);
  1100.                         break;
  1101.                         
  1102.                     case sys7color:
  1103.                         // If the window is not hilited, will use a gray shade
  1104.                         // to draw the window outline in System 7 color.
  1105.                         if (WindData.ignoreHilite || window->hilited)
  1106.                             SetWctbColor(window, wFrameColor);
  1107.                         else {
  1108.                             AvgWctbColor(window, wHiliteColorLight, wHiliteColorDark,
  1109.                                          wInactiveFramePct, &theColor);
  1110.                             RGBForeColor(&theColor);
  1111.                         }
  1112.                         break;
  1113.                 }
  1114.                 FrameRect(&tempRect);
  1115.                 
  1116.                 ForeColor(blackColor);                // draw shadow
  1117.                 MoveTo(tempRect.right, tempRect.top+1);
  1118.                 LineTo(tempRect.right, tempRect.bottom);
  1119.                 LineTo(tempRect.left + 1, tempRect.bottom);
  1120.             break;
  1121.  
  1122.             case wInGoAway:                            // toggle go-away
  1123.                 GetTitleBar(window, &titleRect);
  1124.                 GetCloseBox(window, &titleRect, &tempRect);
  1125.                 if (WindData.closeToggle)
  1126.                     DrawCloseBox(window, fancy, &tempRect);
  1127.                 else
  1128.                     DrawXedBox(window, fancy, &tempRect);
  1129.             break;
  1130.         
  1131. #ifdef ALLOW_ZOOM
  1132.             default:
  1133.                 if (window->spareFlag) {            // toggle zoom box
  1134.                     GetTitleBar(window, &titleRect);
  1135.                     GetZoomBox(window, &titleRect, &tempRect);
  1136.                     if (WindData.zoomToggle)
  1137.                         DrawZoomBox(window, fancy, &tempRect);
  1138.                     else
  1139.                         DrawXedBox(window, fancy, &tempRect);
  1140.                 }
  1141. #endif
  1142.     }
  1143.     ForeColor(blackColor);
  1144.     BackColor(whiteColor);
  1145. }
  1146.  
  1147. //-----------------------------------------------------------------------------
  1148.  
  1149. void DoWDraw( WindowPeek window, long param ) {
  1150.     WDLDataRec        theUserData;
  1151.     GrafPtr         savePort;
  1152.     RgnHandle         drawRgn;
  1153.     Rect            theRect;
  1154.     GDHandle        theDevice;
  1155.     short            inColor;
  1156.  
  1157.     GetPort(&savePort);
  1158.     SetPort((GrafPtr)window);
  1159.     drawRgn = window->strucRgn;
  1160.     SetPort(savePort);
  1161.     
  1162.     theUserData.wdlWindow = window;
  1163.     theUserData.wdlParam = param;
  1164.  
  1165.     if (WindData.isSystem7) {
  1166.         DeviceLoop(drawRgn, (DeviceLoopDrawingProcPtr)WindoidDrawLoop, 
  1167.                    (long)&theUserData, (DeviceLoopFlags)0);
  1168.     } else {
  1169.         inColor = 0;
  1170.         if (window && WindData.hasCQD) {
  1171.             GetGlobalContentRect(window, &theRect);
  1172.             theDevice = GetMaxDevice(&theRect);
  1173.             
  1174.             if (theDevice)
  1175.                 WindoidDrawLoop((**(**theDevice).gdPMap).pixelSize,  // <-- depth
  1176.                                 (**theDevice).gdFlags, 
  1177.                                 theDevice, &theUserData);
  1178.             else 
  1179.                 WindoidDrawLoop(1, 0, nil, &theUserData);
  1180.             
  1181.             // Do this for pre-System 7. we call WindoidDrawLoop directly, giving
  1182.             // it the information on the device with maximum depth, hoping that
  1183.             // the results will be okay. Only reason it might not be is if you
  1184.             // have a System 6 color window that crosses two monitors that have
  1185.             // differing environments where one doesn't have enough colors to
  1186.             // show the color version. Here, the problem will be only cosmetic,
  1187.             // though. Note: I could have done my own device loop for this case,
  1188.             // but I figured it wasn't common enough for the expense.
  1189.         } else {
  1190.             WindoidDrawLoop(1, 0, nil, &theUserData);
  1191.             // Do this for 68000's
  1192.         }
  1193.     }
  1194.  
  1195.     if (window->visible) {
  1196.         switch (param) {
  1197.             case 0:
  1198.                 // This is so param 0 doesn't get interpreted as a hit in the
  1199.                 // zoom box, incorrectly.
  1200.                 break;
  1201.                 
  1202.             case wInGoAway:                        // toggle go-away
  1203.                 WindData.closeToggle = !(WindData.closeToggle);
  1204.                 break;
  1205.             
  1206. #ifdef ALLOW_ZOOM
  1207.             default:                            // toggle zoom box
  1208.                 WindData.zoomToggle = !(WindData.zoomToggle);
  1209.                 break;
  1210. #endif
  1211.         }
  1212.     }
  1213.     ForeColor(blackColor);
  1214.     BackColor(whiteColor);
  1215. }
  1216.  
  1217. //*****************************************************************************
  1218. //    DoWCalcRgns -- Windoid region calculating routine                                 
  1219. //-----------------------------------------------------------------------------
  1220.  
  1221. void DoWCalcRgns( WindowPeek window, long param ) {
  1222.     #pragma unused(param)
  1223.     Rect        contentRect;
  1224.     Rect        structRect;
  1225.     RgnHandle    tempRgn;
  1226.     GrafPtr        savePort;
  1227.  
  1228.     GetPort(&savePort);
  1229.     SetPort((GrafPtr)window);
  1230.  
  1231.     contentRect = window->port.portRect;
  1232.     OffsetRect(&contentRect, -window->port.portBits.bounds.left,
  1233.                              -window->port.portBits.bounds.top);
  1234.     RectRgn(window->contRgn, &contentRect);
  1235.  
  1236.     // start off with the structure equal to the content
  1237.     structRect = contentRect;
  1238.  
  1239.     // make it include the window frame and titlebar
  1240.     InsetRect(&structRect, -1, -1);
  1241.     if (WindData.hasTitlebar) {
  1242.         if (WindData.isHoriz)
  1243.             structRect.top -= kTitleHeight - 1;
  1244.         else
  1245.             structRect.left -= kTitleHeight - 1;
  1246.     }
  1247.     RectRgn(window->strucRgn, &structRect);
  1248.     
  1249.     // add the shadow to the structure 
  1250.     OffsetRect(&structRect, 1, 1);
  1251.     tempRgn = NewRgn();
  1252.     RectRgn(tempRgn, &structRect);
  1253.     UnionRgn(tempRgn, window->strucRgn, window->strucRgn);
  1254.     DisposeRgn(tempRgn);
  1255.     
  1256.     SetPort(savePort);
  1257. }
  1258.  
  1259. //*****************************************************************************
  1260. //    DoWGrow -- Windoid region calculating routine                                 
  1261. //-----------------------------------------------------------------------------
  1262.     // I don't allow of a grow box in a windoid. If you want one, you will
  1263.     // have to implement these two routines.
  1264.  
  1265. void DoWGrow( WindowPeek window, long param ) {
  1266.     #pragma unused(window, param)
  1267. }
  1268.  
  1269. //*****************************************************************************
  1270. //    DoWDrawGIcon -- Draw the grow icon in the lower right corner                                 
  1271. //-----------------------------------------------------------------------------
  1272.  
  1273. void DoWDrawGIcon( WindowPeek window, long param ) {
  1274.     #pragma unused(window, param)
  1275. }
  1276.  
  1277. //*****************************************************************************
  1278.